package com.market.service.impl;

import com.market.annotation.LogicStrategy;
import com.market.constants.Constants;
import com.market.dao.StrategyRuleDao;
import com.market.domain.entity.RuleActionEntity;
import com.market.domain.entity.RuleMatterEntity;
import com.market.domain.po.StrategyRule;
import com.market.domain.vo.RuleLogicCheckTypeVO;
import com.market.factory.DefaultLogicFactory;
import com.market.service.LogicFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * 权重规则过滤，
 * 1. 权重规则格式；4000:102,103,104,105 5000:102,103,104,105,106,107 6000:102,103,104,105,106,107,108,109
 * 2. 解析数据格式；判断哪个范围符合用户的特定抽奖范围
 */
@Slf4j
@Component
@LogicStrategy(logicMode = DefaultLogicFactory.LogicModel.RULE_WIGHT)
public class RuleWeightLogicFilter implements LogicFilter<RuleActionEntity.RaffleBeforeEntity> {

    @Resource
    private StrategyRuleDao strategyRuleDao;

    public Long userScore = 4500L;
    @Override
    public RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> filter(RuleMatterEntity ruleMatterEntity) {

        log.info("规则过滤-权重范围 userId:{} strategyId:{} ruleModel:{}", ruleMatterEntity.getUserId(), ruleMatterEntity.getStrategyId(), ruleMatterEntity.getRuleModel());

        Long strategyId=ruleMatterEntity.getStrategyId();
        String userId=ruleMatterEntity.getUserId();
        String ruleValue= queryStrategyRuleValue(ruleMatterEntity.getStrategyId(),ruleMatterEntity.getAwardId(),ruleMatterEntity.getRuleModel());

        //根据用户Id查询消耗的积分值
        //{4000,"4000:102,103,...},{6000,"..."},...
        Map<Long,String> analyticalValueGroup = getAnalyticalValue(ruleValue);
        //没有权重rule——value，过
        if(null==analyticalValueGroup||analyticalValueGroup.isEmpty()){
            return RuleActionEntity.<RuleActionEntity.RaffleBeforeEntity>builder()
                    .code(RuleLogicCheckTypeVO.ALLOW.getCode())
                    .info(RuleLogicCheckTypeVO.ALLOW.getInfo())
                    .build();
        }
        //获取key，升序排序
        ArrayList<Long> analyticalSortedKeys = new ArrayList<>(analyticalValueGroup.keySet());
        Collections.sort(analyticalSortedKeys);

        //找出符合用户积分的key
        Long nextValue = analyticalSortedKeys.stream()
                .filter(key->userScore >=key)//对流中的每个 key 进行过滤，只保留满足userScore>= key 的元素
                .findFirst()//获取流中第一个满足过滤条件的元素
                .orElse(null);

        if(null!=nextValue){
            return RuleActionEntity.<RuleActionEntity.RaffleBeforeEntity>builder()
                    .data(RuleActionEntity.RaffleBeforeEntity.builder()
                            .strategyId(strategyId)
                            .ruleWeightValueKey(analyticalValueGroup.get(nextValue))
                            .build())
                    .ruleModel(DefaultLogicFactory.LogicModel.RULE_WIGHT.getCode())
                    .code(RuleLogicCheckTypeVO.TAKE_OVER.getCode())
                    .info(RuleLogicCheckTypeVO.TAKE_OVER.getInfo())
                    .build();
        }
        //用户的积分没有符合的，过
        return RuleActionEntity.<RuleActionEntity.RaffleBeforeEntity>builder()
                .code(RuleLogicCheckTypeVO.ALLOW.getCode())
                .info(RuleLogicCheckTypeVO.ALLOW.getInfo())
                .build();
    }

    private Map<Long, String> getAnalyticalValue(String ruleValue) {

        String[] ruleValueGroups=ruleValue.split(Constants.SPACE);
        HashMap<Long, String> ruleValueMap = new HashMap<>();
        for (String ruleKeyValue : ruleValueGroups) {

            if(ruleKeyValue==null||ruleKeyValue.isEmpty()){
                return ruleValueMap;
            }

            String[] splitKeyValue = ruleKeyValue.split(Constants.COLON);
            if(splitKeyValue.length!=2)
                throw new IllegalArgumentException("rule_weight rule_rule invalid input format"+ruleKeyValue);

            ruleValueMap.put(Long.parseLong(splitKeyValue[0]),ruleKeyValue);
        }
        return ruleValueMap;
    }

    private String queryStrategyRuleValue(Long strategyId, Integer awardId, String ruleModel) {
        StrategyRule strategyRule = new StrategyRule();
        strategyRule.setStrategyId(strategyId);
        strategyRule.setAwardId(awardId);
        strategyRule.setRuleModel(ruleModel);
        return strategyRuleDao.queryStrategyRuleValue(strategyRule);
    }
}
